﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using Core.ChannelProtocol;
using Core.Model;
using Core.Msg;

namespace DataServer.View
{
    /// <summary>
    /// MsgView.xaml 的交互逻辑
    /// </summary>
    public partial class MsgView
    {
        private readonly ObservableCollection<RxTxCommand> rxTxCommands = new ObservableCollection<RxTxCommand>();

        private readonly ObservableCollection<Channel> _channels = new ObservableCollection<Channel>();
        private readonly ObservableCollection<Device> _devices = new ObservableCollection<Device>();
        private Channel selectChannel;
        private Device selectDevice;
        private object _synObj = new object();
        private int _eventCount = 0;

        public MsgView()
        {
           
            InitializeComponent();
            if (DesignerProperties.GetIsInDesignMode(this))
            {
                return;
            }
            this.DataContext = rxTxCommands;
            this.Loaded += MsgView_Loaded;
            this.Unloaded += MsgView_Unloaded;
        }

       

        private void MsgView_Loaded(object sender, RoutedEventArgs e)
        {
            AppManager.MsgCtrl.IsShow = true;
            _channels.Clear();
            List<Channel> channels = AppManager.ChannelDao.GetEntities();
            if (channels != null)
            {
                foreach (Channel ch in channels)
                {
                    _channels.Add(ch);
                }
            }
            cbbChannel.ItemsSource = _channels;
            if (_channels.Count > 0)
            {
                cbbChannel.SelectedItem = _channels[0];
            }

            AddMsgDealEvent();
        }
        private void MsgView_Unloaded(object sender, RoutedEventArgs e)
        {
            lock (_synObj)
            {
                AppManager.MsgCtrl.IsShow = false;
                try
                {
                    foreach (BaseChannel channel in AppManager.Channels)
                    {
                        channel.OnNewMessage -= Channel_OnNewMessage;
                    }
                }
                catch
                {
                }

                _eventCount--;
                if (_eventCount < 0) _eventCount = 0;
            }
           
        }
        public void AddMsgDealEvent()
        {
//            try
//            {
//                foreach (BaseChannel channel in AppManager.Channels)
//                {
//                    channel.OnNewMessage -= Channel_OnNewMessage;
//                }
//            }
//            catch
//            {
//            }
            lock (_synObj)
            {
                if(_eventCount>0) return;
                try
                {
                    foreach (IChannel channel in AppManager.Channels)
                    {
                        channel.OnNewMessage += Channel_OnNewMessage;
                    }
                }
                catch
                {
                }
                _eventCount++;
            }
           
        }

       

        private void Channel_OnNewMessage(object sender, EventArgs e)
        {
            if (sender is RxTxCommand cmd)
            {
                this.Dispatcher.BeginInvoke(new Action(() =>
                {
                    if(frozenMsgMenuItem.IsChecked)
                        return;
                    if (filterMenuItem.IsChecked)
                    {
                        if (selectDevice != null)
                        {
                            if (selectDevice.Id != cmd.DeviceId) return;
                        }
                        else if(selectChannel !=null)
                        {
                            if(selectChannel.Id != cmd.ChannelId)return;
                        }
                        
                    }
                    rxTxCommands.Add(cmd);
                    if (rxTxCommands.Count > 100)
                    {
                        rxTxCommands.RemoveAt(0);
                    }
                    if (listViewMsg.Items.Count > 0)
                    {
                        listViewMsg.ScrollIntoView(listViewMsg.Items[listViewMsg.Items.Count - 1]);
                    }
                }));
            }
        }

        private void ClearLogMsg_OnClick(object sender, RoutedEventArgs e)
        {
            //listViewMsg.Items.Clear(); //报错：当 ItemsSource 正在使用时操作无效。改用 ItemsControl.ItemsSource 访问和修改元素
            rxTxCommands.Clear();
        }

        private void FrozenLogMsg_OnClick(object sender, RoutedEventArgs e)
        {
            frozenMsgMenuItem.IsChecked = !frozenMsgMenuItem.IsChecked;
        }

        private void FilterMenuItem_OnClick(object sender, RoutedEventArgs e)
        {
            filterMenuItem.IsChecked = !filterMenuItem.IsChecked;
            if (filterMenuItem.IsChecked)
            {
                grid.RowDefinitions[1].Height = new GridLength(26);
                rxTxCommands.Clear();
            }
            else
            {
                grid.RowDefinitions[1].Height = new GridLength(0);
                AppManager.MsgCtrl.SelectedChlId = "";
                AppManager.MsgCtrl.SelectedDevId = "";
            }
            
        }

        private void CcbChannel_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            AppManager.MsgCtrl.SelectedChlId = "";
            AppManager.MsgCtrl.SelectedDevId = "";
            selectDevice = null;
            selectChannel = cbbChannel.SelectedItem as Channel;
            rxTxCommands.Clear();
            _devices.Clear();
            if (selectChannel != null)
            {
                AppManager.MsgCtrl.SelectedChlId = selectChannel.Id;
                List<Device> devices = AppManager.DeviceDao.GetDevicesByChlId(selectChannel.Id);
                if (devices != null)
                {
                    foreach (Device dev in devices)
                    {
                        _devices.Add(dev);
                    }
                }
               
            }
            cbbDevice.ItemsSource = _devices;
        }

        private void CcbDevice_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            selectDevice = cbbDevice.SelectedItem as Device;
            if (selectDevice != null)
            {
                AppManager.MsgCtrl.SelectedChlId = selectDevice.Id;
            }
            rxTxCommands.Clear();
        }

        private void BtnReset_OnClick(object sender, RoutedEventArgs e)
        {
            cbbChannel.SelectedIndex = -1;
            cbbDevice.SelectedIndex = -1;
            selectChannel = null;
            selectDevice = null;
            AppManager.MsgCtrl.SelectedChlId = "";
            AppManager.MsgCtrl.SelectedDevId = "";
        }


        private void BtnHide_OnClick(object sender, RoutedEventArgs e)
        {
            filterMenuItem.IsChecked = false;
            AppManager.MsgCtrl.SelectedChlId = "";
            AppManager.MsgCtrl.SelectedDevId = "";
            grid.RowDefinitions[1].Height = new GridLength(0);
        }
    }
    #region Converter

    public class ByteConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            string content = "";
            try
            {
                bool isAscii = (bool)values[0];
                byte[] datas = values[1] as byte[];
                if (datas != null && datas.Length > 0)
                {
                    if (isAscii)
                    {
                        content = Encoding.ASCII.GetString(datas);
                    }
                    else
                    {
                        StringBuilder stringBuilder = new StringBuilder();
                        foreach (byte b in datas)
                        {
                            stringBuilder.Append(b.ToString("X2"));
                            stringBuilder.Append(" ");
                        }
                        content = stringBuilder.ToString();
                    }
                }
            }
            catch
            {

            }
            return content;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException("未实现!");
            //string[] splitValues = ((string)value).Split(' ');
            //return splitValues;
        }
    }
    [ValueConversion(typeof(MsgResult), typeof(BitmapImage))]
    public class ImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null) return null;
            var val = (MsgResult)Enum.Parse(typeof(MsgResult), value.ToString());
            switch (val)
            {
                case MsgResult.RecOk:
                    return new BitmapImage(new Uri("../Resource/Image/ok.png", UriKind.Relative));
                case MsgResult.RecErr:
                    return new BitmapImage(new Uri("../Resource/Image/error.png", UriKind.Relative));
                case MsgResult.RecTimeout:
                    return new BitmapImage(new Uri("../Resource/Image/error.png", UriKind.Relative));
                default:
                    return new BitmapImage(new Uri("../Resource/Image/alert.png", UriKind.Relative));
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException("未实现!");
        }
    }

    #endregion

}
